#ifndef cathlibcpp_stdiobuf_H
#define cathlibcpp_stdiobuf_H

// File:       stdiobuf.h
// Author:     (c) Miles Sabin, 1997
// Purpose:    streambuf wrapper for C style FILEs

// See stdiobuf.c++ for default buffer size


#ifndef cathlibcpp_config_H
#include "config.h"
#endif

#ifndef cathlibcpp_streambuf_H
#include "streambuf.h"
#endif

#ifndef cathlibcpp_string_H
#include "string.h"             // for char_traits_char
#endif


struct __FILE_struct;
typedef __FILE_struct FILE;


class stdiobuf : public basic_streambuf_char
{
  friend class StdiobufSync;

  public:

    // types
    typedef char_traits_char traits;

    // constructors
    stdiobuf(FILE* file = 0, streamsize buffer_size = -1);
    virtual ~stdiobuf();

    bool is_open() const;
    stdiobuf* open(char const* s, ios::openmode mode, streamsize buffer_size = -1);
    stdiobuf* close();

  protected:

    int showmanyc();
    streamsize xsgetn(char* s, streamsize n);
    int underflow();

    int pbackfail(int c = traits::eof());

    streamsize xsputn(char const* s, streamsize n);
    int overflow(int c = traits::eof());

    basic_streambuf_char* setbuf(char* s, streamsize n);
    int seekoff(int off, ios::seekdir way, ios::openmode which = ios::in|ios::out);
    int seekpos(int sp, ios::openmode which = ios::in|ios::out);

    int sync();

  private:

    bool create_buffer();

    void sync_stream_with_stdio();
    void sync_stdio_with_stream();

    void real_sync_stream_with_stdio();
    void real_sync_stdio_with_stream();

    FILE* file_;
    char* buffer_;
    int buffer_size_;
};

#endif
